package com.bringspring.oauth.config;

import com.bringspring.common.util.CacheKeyUtil;
import com.bringspring.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class MyRoleHierarchy implements RoleHierarchy {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CacheKeyUtil cacheKeyUtil;

    /**
     * 登录时添加权限表示为管理员账号, 获取管理员账号权限集合
     */
    public static final SimpleGrantedAuthority adminAuth = new SimpleGrantedAuthority("isAdmin");

    @Override
    public Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(Collection<? extends GrantedAuthority> authorities) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null){
            boolean isAdmin = authorities.size()==1 && authorities.contains(adminAuth);
            String interfacePermissionKey = CacheKeyUtil.USERAUTHORIZE + ":" + cacheKeyUtil.getUserAuthorize() + "authority_" + (isAdmin?"admin":authentication.getName());
            String rolesKey = CacheKeyUtil.USERAUTHORIZE + ":" + cacheKeyUtil.getUserAuthorize() + "role_" + (isAdmin?"admin":authentication.getName());
            Set<Object> permissions = Optional.ofNullable(redisUtil.getSet(interfacePermissionKey)).orElse(new HashSet<>());
            permissions.addAll(Optional.ofNullable(redisUtil.getSet(rolesKey)).orElse(Collections.emptySet()));
            Set<GrantedAuthority> permissionList = permissions.stream().map(s->new SimpleGrantedAuthority(s.toString())).collect(Collectors.toSet());
            return permissionList;
        }
        return Collections.emptyList();
    }

    @Bean
    public HttpFirewall httpFirewall(){
        return new DefaultHttpFirewall();
    }
}
